#ifndef _MESSAGER_H_
#define _MESSAGER_H_

#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>

#include "FreeRTOS.h"
#include "task.h"
#include "queue.h"
#include "semphr.h"

// ##
#define MESSAGE_MAX_LENGTH 256

/*
 * ARM Compiler 4/5
 */
#if   defined ( __CC_ARM )

    #define __ASM            __asm
    #define __INLINE         __inline
    #define __STATIC_INLINE  static __inline

    #include "cmsis_armcc.h"

/*
 * GNU Compiler
 */
#elif defined ( __GNUC__ )

    #define __ASM            __asm                                      /*!< asm keyword for GNU Compiler          */
    #define __INLINE         inline                                     /*!< inline keyword for GNU Compiler       */
    #define __STATIC_INLINE  static inline

    #ifndef SIMULATOR
    #include "cmsis_gcc.h"
    #endif

/*
 * IAR Compiler
 */
#elif defined ( __ICCARM__ )

    #ifndef   __ASM
    #define __ASM                     __asm
    #endif
    #ifndef   __INLINE
    #define __INLINE                  inline
    #endif
    #ifndef   __STATIC_INLINE
    #define __STATIC_INLINE           static inline
    #endif

    #include <cmsis_iar.h>
#endif

// ##
typedef enum
{
    MSG_START = 0,

    // ##
    MSG_RTC_SET_UTC,

    // ##
    MSG_BTN_EVENT,

    // ##
    MSG_RTC_ALARM,
    MSG_RTC_ALARM_BROADCAST,
    MSG_RTC_SET_TIME,

    // ##
    MSG_WIFI_ON,
    MSG_WIFI_OFF,
    MSG_WIFI_CONNECT,
    MSG_WIFI_DISCONNECT,

    // ##
    MSG_ACTIVITY_SWITCH,

    // ##
    MSG_END
}msg_t;

// ##
typedef enum
{
    RESULT_OK = 0,
    RESULT_ERR,
}mResult_t;

// ##
typedef QueueHandle_t mMessager_t;

// ##
mResult_t messager_init(void);

// ##
mMessager_t messager_create(uint8_t depth);

// ##
mResult_t messager_bind(msg_t msg, mMessager_t queue);

// ##
mResult_t messager_unbind(msg_t msg, mMessager_t queue);

// ##
mResult_t messager_post(msg_t msg, void *content, uint32_t length, uint32_t flag);

// ##
mResult_t messager_notify(msg_t msg, uint32_t notification);

// ##
mResult_t messager_mail(msg_t msg, void *content, uint32_t size);

// ##
mResult_t messager_recv(mMessager_t queue, msg_t *msg_id, void *content, uint32_t *sLength, uint32_t dLength);

// ##
mResult_t messager_register(mMessager_t mail, uint32_t *mail_list, uint32_t len);

// ##
mResult_t messager_unregister(mMessager_t mail, uint32_t *mail_list, uint32_t len);

// ##
mResult_t messager_recv_timeout(mMessager_t queue, msg_t *msg, void *content, uint32_t *content_size, uint32_t buffer_size,int ms);

#endif
